/*
 *
 *   Copyright (C) 2005 by Raymond Huang
 *   plushuang at users.sourceforge.net
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of portions of this program with the
 *  OpenSSL library under certain conditions as described in each
 *  individual source file, and distribute linked combinations
 *  including the two.
 *  You must obey the GNU Lesser General Public License in all respects
 *  for all of the code used other than OpenSSL.  If you modify
 *  file(s) with this exception, you may extend this exception to your
 *  version of the file(s), but you are not obligated to do so.  If you
 *  do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source
 *  files in the program, then also delete it here.
 *
 */

#ifndef __URL_FILTER_H
#define __URL_FILTER_H

#include <glib.h>
#include <urlglib/urlglib_signal.h>
#include <urlglib/url_info.h>

// Hierarchy :
//
// UrlItemList
// |
// +--- UrlFilter
// |
// `--- UrlFilterClass
//


// Run time memory:
//
// UrlItem
// |
// `--- related_list
//      |
//      ... other related UrlItem
//
//
// UrlFilter (Base on UrlItemList)
// |
// +--- item_list
// |    |
// |    `--- UrlItem
// |
// `--- class_list
//      |
//      +--- UrlFilterClass 1 (Base on UrlItemList)
//      |    |
//      |    `--- item_list
//      |         |
//      |         `--- UrlItem
//      |              |
//      |              `--- related_list (related UrlItem from UrlFilter->item_list)
//      |
//      `--- UrlFilterClass 2 (Base on UrlItemList)
//           |
//           `--- item_list
//                |
//                `--- UrlItem
//                     |
//                     `--- related_list (related UrlItem from UrlFilter->item_list)
//

#ifdef __cplusplus
extern "C" {
#endif

#define URL_ITEM_LIST_FIELDS                  \
	UrlItemListFinalizeFunc  finalize;        \
	GSList*                  added_signal;    \
	GSList*                  item_list;       \
	GSList*                  item_list_tail;  \
	int                      reference_count

#define URL_ITEM_LIST(o)     ((UrlItemList*)(o))

typedef struct _UrlItem        UrlItem;
typedef struct _UrlItemList    UrlItemList;
typedef struct _UrlFilter      UrlFilter;
typedef struct _UrlFilterClass UrlFilterClass;
typedef void (*UrlItemListFinalizeFunc) (UrlItemList *uilist);
typedef void (*UrlItemListCallback) (UrlItemList *uilist, UrlItem* uitem, GSList* slist, gpointer data);
typedef void (*UrlFilterClassFunc) (UrlFilterClass* fclass, UrlItem* uitem, UrlInfo* uinfo);

// UrlItem -----------------------------------------------------------

struct _UrlItem {
	int       reference_count;
	int       picked_count;
	gboolean  mark;
	gchar*    string;
	GSList*   related_list;    // for UrlFilterClass
};

UrlItem* url_item_new (char* string, int len);
void  url_item_ref (UrlItem* uitem);
void  url_item_unref (UrlItem* uitem);
void  url_item_add_related (UrlItem* uitem, UrlItem* related_item);
void  url_item_pick_related_item (UrlItem* uitem);

// UrlItemList -------------------------------------------------------

struct _UrlItemList {
	URL_ITEM_LIST_FIELDS;
};

void url_item_list_instance_init (UrlItemList* uilist);
void url_item_list_instance_finalize (UrlItemList* uilist);

void url_item_list_ref (UrlItemList* uilist);
void url_item_list_unref (UrlItemList* uilist);

void url_item_list_add (UrlItemList* uilist, UrlItem* uitem);
void url_item_list_set_item_all (UrlItemList* uilist, gboolean mark, int picked_count);

// notify callback & setup functions ---
#define url_item_list_added_connect(uilist, cb, data)    \
            urlglib_signal_connect (&(uilist)->added_signal, (UrlglibCallback)cb, data)
#define url_item_list_added_disconnect(uilist, sig)      \
            urlglib_signal_disconnect (&(uilist)->added_signal, sig)

#define url_item_list_length(uilist)   g_slist_length ((uilist)->item_list)
void url_item_list_item_added (UrlItemList* uilist, UrlItem* uitem, GSList* slist);

// UrlFilter ---------------------------------------------------------

struct _UrlFilter {
	URL_ITEM_LIST_FIELDS;

	GSList*  class_list;   // UrlFilterClass
	UrlInfo  url_info;
};

UrlFilter* url_filter_new ();

#define url_filter_ref(obj)    url_item_list_ref ((UrlItemList*)obj);
#define url_filter_unref(obj)  url_item_list_unref ((UrlItemList*)obj);

// void url_filter_set_item_all (UrlFilter* filter, gboolean mark, int picked_count);
#define url_filter_set_item_all(obj,m,c)    url_item_list_set_item_all (URL_ITEM_LIST (obj),m,c)

void url_filter_add_class (UrlFilter* filter, UrlFilterClass* fclass);
UrlFilterClass* url_filter_get_class (UrlFilter* filter, UrlFilterClassFunc func);

void url_filter_add_item (UrlFilter* filter, char* url, char* base_href);
void url_filter_add_item_len (UrlFilter* filter, char* url, int url_len, char* base_href);
void url_filter_mark_item (UrlFilter* filter, int min_pick_count, int max_pick_count);

// if n_marked != NULL, n_marked == number of marked UrlItem
GSList* url_filter_get_marked_item (UrlFilter* filter, int* n_marked);
void url_filter_pick_by_marked_class (UrlFilter* filter);

// UrlFilterClass ----------------------------------------------------

struct _UrlFilterClass {
	URL_ITEM_LIST_FIELDS;

	UrlFilterClassFunc  class_func;
	GHashTable*  hash_table;
};

UrlFilterClass* url_filter_class_new (UrlFilterClassFunc fn);

#define url_filter_class_set_item_all(obj,m,c)    url_item_list_set_item_all (URL_ITEM_LIST (obj),m,c)
void url_filter_class_pick_marked_item (UrlFilterClass* fclass);

#define url_filter_class_ref(obj)    url_item_list_ref (URL_ITEM_LIST (obj))
#define url_filter_class_unref(obj)  url_item_list_unref (URL_ITEM_LIST (obj))
#define url_filter_class_add(obj,i)  url_item_list_add (URL_ITEM_LIST (obj),i)

// For UrlFilterClassFunc ---
void url_filter_class_protocol (UrlFilterClass* ufclass, UrlItem* uitem, UrlInfo* uinfo);
void url_filter_class_address (UrlFilterClass* ufclass, UrlItem* uitem, UrlInfo* uinfo);
void url_filter_class_extension (UrlFilterClass* ufclass, UrlItem* uitem, UrlInfo* uinfo);

#ifdef __cplusplus
}
#endif

#endif  // End of __URL_FILTER_H

